package com.lineage.server.model;

import com.lineage.server.model.Instance.L1NpcInstance;
import com.lineage.server.model.Instance.L1PcInstance;
import com.lineage.server.serverpackets.S_DoActionGFX;
import com.lineage.server.serverpackets.S_EffectLocation;
import com.lineage.server.serverpackets.ServerBasePacket;
import com.lineage.server.thread.GeneralThreadPool;
import java.util.Random;
import java.util.TimerTask;
import java.util.concurrent.ScheduledFuture;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class L1Chaser extends TimerTask {
  private static final Log _log = LogFactory.getLog(L1Chaser.class);
  
  private static final Random _random = new Random();
  
  private ScheduledFuture<?> _future;
  
  private int _timeCounter;
  
  private final L1PcInstance _pc;
  
  private final L1Character _cha;
  
  public L1Chaser(L1PcInstance pc, L1Character cha) {
    this._future = null;
    this._timeCounter = 0;
    this._cha = cha;
    this._pc = pc;
  }
  
  public void run() {
    try {
      if (this._cha == null || this._cha.isDead()) {
        stop();
        return;
      } 
      attack();
      this._timeCounter++;
      if (this._timeCounter >= 3) {
        stop();
        return;
      } 
    } catch (Throwable e) {
      _log.error(e.getLocalizedMessage(), e);
    } 
  }
  
  public void begin() {
    this._future = GeneralThreadPool.get().scheduleAtFixedRate(this, 0L, 1000L);
  }
  
  public void stop() {
    if (this._future != null)
      this._future.cancel(false); 
  }
  
  private void attack() {
    double damage = getDamage(this._pc, this._cha);
    if (this._cha.getCurrentHp() - (int)damage <= 0 && this._cha.getCurrentHp() != 1) {
      damage = (this._cha.getCurrentHp() - 1);
    } else if (this._cha.getCurrentHp() == 1) {
      damage = 0.0D;
    } 
    this._pc.sendPacketsAll((ServerBasePacket)new S_EffectLocation(this._cha.getX(), this._cha.getY(), 7025));
    if (this._cha instanceof L1PcInstance) {
      L1PcInstance pc = (L1PcInstance)this._cha;
      pc.sendPacketsAll((ServerBasePacket)new S_DoActionGFX(pc.getId(), 2));
      pc.receiveDamage((L1Character)this._pc, damage, false, false);
    } else if (this._cha instanceof L1NpcInstance) {
      L1NpcInstance npc = (L1NpcInstance)this._cha;
      npc.broadcastPacketX10((ServerBasePacket)new S_DoActionGFX(npc.getId(), 2));
      npc.receiveDamage((L1Character)this._pc, (int)damage);
    } 
  }
  
  private double getDamage(L1PcInstance pc, L1Character cha) {
    double dmg = 0.0D;
    int spByItem = pc.getSp() - pc.getTrueSp();
    int intel = pc.getInt();
    int charaIntelligence = pc.getInt() + spByItem - 12;
    double coefficientA = 1.0D + 0.09375D * charaIntelligence;
    if (coefficientA < 1.0D)
      coefficientA = 1.0D; 
    double coefficientB = 0.0D;
    if (intel > 25) {
      coefficientB = 1.625D;
    } else if (intel <= 12) {
      coefficientB = 0.78D;
    } else {
      coefficientB = intel * 0.065D;
    } 
    double coefficientC = 0.0D;
    if (intel > 25) {
      coefficientC = 25.0D;
    } else if (intel <= 12) {
      coefficientC = 12.0D;
    } else {
      coefficientC = intel;
    } 
    double bsk = 0.0D;
    if (pc.hasSkillEffect(55))
      bsk = 0.1D; 
    dmg = (_random.nextInt(6) + 1 + 7) * (1.0D + bsk) * coefficientA * coefficientB / 10.5D * coefficientC * 
      2.0D;
    return L1WeaponSkill.calcDamageReduction(pc, cha, dmg, 0) * 0.66D;
  }
}
